/**
 * ErrorBoundary.js
 * 
 * 前端全局错误边界
 * 职责:
 * 1. 捕获未处理的错误和 Promise 拒绝
 * 2. 显示友好的错误提示
 * 3. 记录错误日志
 */

(function() {
    'use strict';

    class ErrorBoundary {
        constructor() {
            this.errorCount = 0;
            this.maxErrors = 10; // 最大错误数,防止错误风暴
            this._init();
        }

        /**
         * 初始化全局错误监听
         * @private
         */
        _init() {
            // 捕获同步错误
            window.addEventListener('error', (event) => {
                this._handleError({
                    message: event.message,
                    source: event.filename,
                    line: event.lineno,
                    column: event.colno,
                    error: event.error
                });
                event.preventDefault(); // 阻止默认错误处理
            });

            // 捕获 Promise 未处理的拒绝
            window.addEventListener('unhandledrejection', (event) => {
                this._handleError({
                    message: 'Unhandled Promise Rejection',
                    error: event.reason
                });
                event.preventDefault();
            });

            console.log('[ErrorBoundary] Initialized');
        }

        /**
         * 处理错误
         * @private
         */
        _handleError(errorInfo) {
            this.errorCount++;

            // 防止错误风暴
            if (this.errorCount > this.maxErrors) {
                console.error('[ErrorBoundary] Too many errors, suppressing further notifications');
                return;
            }

            // 记录到控制台
            console.error('[ErrorBoundary] Caught error:', errorInfo);

            // 显示错误提示
            this._showErrorNotification(errorInfo);

            // 重置错误计数 (5秒后)
            setTimeout(() => {
                this.errorCount = Math.max(0, this.errorCount - 1);
            }, 5000);
        }

        /**
         * 显示错误通知
         * @private
         */
        _showErrorNotification(errorInfo) {
            const errorMessage = errorInfo.error?.message || errorInfo.message || 'Unknown error';
            
            // 创建错误提示元素
            const notification = document.createElement('div');
            notification.className = 'error-notification';
            notification.innerHTML = `
                <div class="error-content">
                    <span class="codicon codicon-error"></span>
                    <span class="error-message">${this._escapeHtml(errorMessage)}</span>
                    <button class="error-close-btn" title="关闭">
                        <span class="codicon codicon-close"></span>
                    </button>
                </div>
            `;

            // 添加到页面
            document.body.appendChild(notification);

            // 绑定关闭按钮
            const closeBtn = notification.querySelector('.error-close-btn');
            closeBtn.onclick = () => {
                notification.remove();
            };

            // 5秒后自动移除
            setTimeout(() => {
                if (notification.parentElement) {
                    notification.remove();
                }
            }, 5000);
        }

        /**
         * HTML 转义
         * @private
         */
        _escapeHtml(text) {
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }

        /**
         * 手动报告错误
         */
        static reportError(error, context = '') {
            console.error(`[ErrorBoundary] ${context}:`, error);
            
            const errorInfo = {
                message: context || 'Application error',
                error: error instanceof Error ? error : new Error(String(error))
            };

            // 触发错误处理
            if (window.errorBoundary) {
                window.errorBoundary._handleError(errorInfo);
            }
        }

        /**
         * 包装异步函数
         */
        static async wrapAsync(fn, errorMessage = 'Operation failed') {
            try {
                return await fn();
            } catch (error) {
                ErrorBoundary.reportError(error, errorMessage);
                return undefined;
            }
        }
    }

    // 暴露到全局
    window.ErrorBoundary = ErrorBoundary;

    // 自动初始化
    window.errorBoundary = new ErrorBoundary();
})();
